package cn.iocoder.yudao.module.infra.listener;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.read.listener.ReadListener;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;


public class ErrorContinuingReadListener<T> implements ReadListener<T> {


    // 收集错误信息的列表
    private final List<String> errorMessages = new ArrayList<>();

    // 成功解析的对象
    private final List<T> successData = new ArrayList<>();

    @Override
    public void invoke(T data, AnalysisContext context) {
        // 正常处理每一行数据
       /* successData.add(data);*/
        // 这里可以添加业务处理逻辑...
        System.out.println("成功处理数据: " + data);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 所有数据处理完成后调用
        if (!errorMessages.isEmpty()) {
            System.out.println("==== 处理完成，有 " + errorMessages.size() + " 个错误 ====");
            errorMessages.forEach(System.out::println);
        } else {
            System.out.println("==== 所有数据成功导入 ====");
        }
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) {
        // 当发生异常时，记录错误但不中断流程
        String errorMsg = "错误数据位置：";

        // 提取行号信息
        int rowIndex = 0;
        int columnIndex = 0;

        if (context.readRowHolder() != null) {
            rowIndex = context.readRowHolder().getRowIndex() + 1; // Excel行号从1开始
        }

        if (exception instanceof ExcelDataConvertException) {
            ExcelDataConvertException excelException = (ExcelDataConvertException) exception;
            columnIndex = excelException.getColumnIndex() + 1; // Excel列号从1开始
        }

        // 添加位置信息
        errorMsg += String.format(" (行: %d, 列: %d)", rowIndex, columnIndex);

        // 添加异常详情
//        errorMsg += " - " + exception.getMessage();

        String s = null;

        // 提取根因
        Throwable rootCause = getRootCause(exception);
        if (rootCause != null) {
            errorMsg += " - [根因] " + rootCause.getMessage();
            s = errorMsg.replaceFirst("-.*(：)", "$1");

            //获取字符位置
            int firstColon = s.indexOf(':');
            int secondColon = s.indexOf('：', firstColon + 1);

            //分割获取两个数据
            String part1 = s.substring(0, secondColon);
            String part2 = s.substring(secondColon + 1);

            //中间插入文字
            s = part1 + "   错误数据：" + part2;

        }



        // 添加到错误列表
        errorMessages.add(s);
    }

    // 获取根本原因
    private Throwable getRootCause(Throwable throwable) {
        Throwable root = throwable;
        while (root.getCause() != null && root.getCause() != root) {
            root = root.getCause();
        }
        return root;
    }

    public List<T> getSuccessData() {
        return successData;
    }

    public List<String> getErrors() {
        return errorMessages;
    }
}
